home *** CD-ROM | disk | FTP | other *** search
-
-
-
- Chapter 9
- MULTIPLE INHERITANCE AND FUTURE DIRECTIONS
-
- Multiple inheritance is the ability to inherit data and methods
- from more than one class into a subclass. Multiple inheritance
- and a few of the other recent additions to the language will be
- discussed in this chapter along with some of the expected future
- directions of the language.
-
- Several companies have C++ compilers available in the
- marketplace, and others are sure to follow. Because the example
- programs in this tutorial are designed to be as generic as
- possible, most should be compilable with any good quality C++
- compiler provided it follows the AT&T definition of version 2.1
- or newer. Many of these examples will not work with earlier
- definitions because the language was significantly changed with
- the version 2.1 update.
-
- After completing this tutorial, you should have enough experience
- with the language to study additional new constructs on your own
- as they are implemented by the various compiler writers. We will
- update the entire tutorial as soon as practical following
- procurement of any new compiler, but hopefully the language will
- not change rapidly enough now to warrant an update oftener than
- annually. Please feel free to contact us for information on
- updates to the Coronado Enterprises C++ tutorial.
-
-
- MULTIPLE INHERITANCE
- -----------------------------------------------------------------
- A major recent addition to the C++ language is the ability to
- inherit methods and variables from two or more parent classes
- when building a new class. This is called multiple inheritance,
- and is purported by many people to be a major requirement for an
- object oriented programming language. Some writers, however,
- have expressed doubts as to the utility of multiple inheritance.
- To illustrate the validity of this, it was not easy to think up a
- good example of the use of multiple inheritance as an
- illustration for this chapter. In fact, the resulting example is
- sort of a forced example that really does nothing useful. It
- does however, illustrate the mechanics of the use of multiple
- inheritance with C++, and that is our primary concern at this
- time.
-
- The biggest problem with multiple inheritance involves the
- inheritance of variables or methods from two or more parent
- classes with the same name. Which variable or method should be
- chosen as the inherited variable or method if two or more have
- the same name? This will be illustrated in the next few example
- programs.
-
-
-
- Page 9-1
-
- Chapter 9 - Multiple Inheritance and Future Directions
-
- SIMPLE MULTIPLE INHERITANCE
- -----------------------------------------------------------------
- An examination of the file named MULTINH1.CPP ==================
- will reveal the definition of two very simple MULTINH1.CPP
- classes in lines 4 through 27 named ==================
- moving_van and driver. In order to keep the
- program as simple as possible, all of the member methods are
- defined as inline functions. This puts the code for the methods
- where it is easy to find and study. You will also notice that
- all variables in both classes are declared to be protected so
- they will be readily available for use in any class which
- inherits them. The code for each class is kept very simple so
- that we can concentrate on studying the interface to the methods
- rather than spending time trying to understand complex methods.
- As mentioned previously, chapter 12 will illustrate the use of
- non-trivial methods.
-
- In line 30, we define another class named driven_truck which
- inherits all of the data and all of the methods from both of the
- previously defined classes. In the last two chapters, we studied
- how to inherit a single class into another class, and to inherit
- two or more classes, the same technique is used except that we
- use a list of inherited classes separated by commas as
- illustrated in line 30. The observant student will notice that
- we use the keyword public prior to the name of each inherited
- class in order to be able to freely use the methods within the
- subclass. In this case, we didn't define any new variables, but
- we did introduce two new methods into the subclass in lines 32
- through 39.
-
- We declared an object named chuck_ford which presumably refers to
- someone named Chuck who is driving a Ford moving van. The object
- named chuck_ford is composed of four variables, three from the
- moving_van class, and one from the driver class. Any of these
- four variables can be manipulated in any of the methods defined
- within the driven_truck class in the same way as in a singly
- inherited situation. A few examples are given in lines 47
- through 56 of the main program and the diligent student should be
- able to add additional output messages to this program if he
- understands the principles involved.
-
- All of the rules for private or protected variables and public or
- private method inheritance as used with single inheritance
- extends to multiple inheritance.
-
-
- DUPLICATED METHOD NAMES
- -----------------------------------------------------------------
- You will notice that both of the parent classes have a method
- named initialize(), and both of these are inherited into the
- subclass with no difficulty. However, if we attempt to send a
- message to one of these methods, we will have a problem, because
-
-
- Page 9-2
-
- Chapter 9 - Multiple Inheritance and Future Directions
-
- the system does not know which we are referring to. This problem
- will be solved and illustrated in the next example program.
-
- Before going on to the next example program, it should be noted
- that we have not declared any objects of the two parent classes
- in the main program. Since the two parent classes are simply
- normal classes themselves, it should be apparent that there is
- nothing magic about them and they can be used to define and
- manipulate objects in the usual fashion. You may wish to do this
- to review your knowledge of simple classes and objects of those
- classes.
-
- Be sure to compile and execute this program after you understand
- its operation completely.
-
-
- MORE DUPLICATE METHOD NAMES
- -----------------------------------------------------------------
- The second example program in this chapter ==================
- named MULTINH2.CPP, illustrates the use of MULTINH2.CPP
- classes with duplicate method names being ==================
- inherited into a derived class. If you
- study the code, you will find that a new method has been added to
- all three of the classes named cost_per_full_day(). This was
- done intentionally to illustrate how the same method name can be
- used in all three classes. The class definitions are no problem
- at all, the methods are simply named and defined as shown. The
- problem comes when we wish to use one of the methods since they
- are all the same name and they have the same numbers and types of
- parameters and identical return types. This prevents some sort
- of an overloading rule to disambiguate the message sent to one or
- more of the methods.
-
- The method used to disambiguate the method calls are illustrated
- in lines 60, 64, and 68 of the main program. The solution is to
- prepend the class name to the method name with the double colon
- as used in the method implementation definition. This is
- referred to as qualifying the method name. Qualification is not
- necessary in line 68 since it is the method in the derived class
- and it will take precedence over the other method names.
- Actually, you could qualify all method calls, but if the names
- are unique, the compiler can do it for you and make your code
- easier to write and read.
-
- Be sure to compile and execute this program and study the
- results. The observant student will notice that there is a slight
- discrepancy in the results given in lines 79 through 81, since the
- first two values do not add up to the third value exactly. This
- is due to the limited precision of the float variable but should
- cause no real problem.
-
-
-
-
- Page 9-3
-
- Chapter 9 - Multiple Inheritance and Future Directions
-
- DUPLICATED VARIABLE NAMES
- -----------------------------------------------------------------
- If you will examine the example program named ==================
- MULTINH3.CPP, you will notice that each base MULTINH3.CPP
- class has a variable with the same name. ==================
-
- According to the rules of inheritance, an object of the
- driven_truck class will have two variables with the same name,
- weight. This would be a problem if it weren't for the fact that
- C++ has defined a method of accessing each one in a well defined
- way. You have probably guessed that we will use qualification to
- access each variable. Lines 38 and 45 illustrate the use of the
- variables. It may be obvious, but it should be explicitly
- stated, that there is no reason that the subclass itself cannot
- have a variable of the same name as those inherited from the
- parent classes. In order to access it, no qualification would
- be required.
-
- It should be apparent to you that once you understand single
- inheritance, multiple inheritance is nothing more than an
- extension of the same rules. Of course, if you inherit two
- methods or variables of the same name, you must use qualification
- to allow the compiler to select the correct one.
-
- Constructors are called for both classes before the derived class
- constructor is executed. The constructors for the base classes
- are called in the order they are declared in the class header
- line.
-
-
- PRACTICAL MULTIPLE INHERITANCE
- -----------------------------------------------------------------
- Examine the example program named DATETIME.H ==================
- for a practical example using multiple DATETIME.H
- inheritance. You will notice that we are ==================
- returning to our familiar new_date and
- time_of_day classes from earlier chapters.
-
- There is a good deal to be learned from this very short header
- file since it is our first example of member initialization.
- There are two constructors for this class, the first being a very
- simple constructor that does nothing in itself, as is evident
- from an examination of line 12. This constructor allows the
- constructors to be executed for the classes new_date and
- time_of_day. In both cases a constructor will be executed that
- requires no parameters, and such a constructor is available for
- each of these two classes.
-
- The second constructor is more interesting since it does not
- simply use the default constructor, but instead passes some of
- the input parameters to the inherited class constructors.
- Following the colon in line 13 are two member initializers which
- are used to initialize members of this class. Since the two
-
- Page 9-4
-
- Chapter 9 - Multiple Inheritance and Future Directions
-
- parent classes are inherited, they are also members of this class
- and can be initialized as shown. Each of the member initializers
- is actually a call to a constructor of the parent classes and it
- should be evident that there must be a constructor with the
- proper number of input parameters to respond to the messages
- given. You will note that in line 14, we are actually calling
- the constructor with no parameters given explicitly. If we
- chose, we could simply let the system call that constructor
- automatically, but this gives us an explicit comment on what is
- happening.
-
-
- MORE ABOUT MEMBER INITIALIZERS
- -----------------------------------------------------------------
- Actually, we can use the member initializer to initialize class
- members also. If we had a class member of type int named
- member_var, we could initialize it also by mentioning the name of
- the member followed by the value we desired to initialize it to
- in parentheses. If we wished to initialize it to the value 13,
- we could use the following line of code in the member initializer
- list;
-
- member_var(13),
-
- Following all member initialization, the normal constructor code
- for the derived class is executed which in this case is given in
- line 16.
-
-
- ORDER OF MEMBER INITIALIZATION
- -----------------------------------------------------------------
- The order of member initialization may seem a bit strange, but it
- does follow a few simple rules. The order of member
- initialization does not follow the order given by the
- initialization list, but another very strict order over which you
- have complete control. All inherited classes are initialized
- first in the order they are listed in the class header. If lines
- 14 and 15 were reversed, class new_date would still be
- initialized first because it is mentioned first in line 8. It
- has been mentioned that C++ respects its elders and initializes
- its parents prior to itself. That should be a useful memory aid
- in the use of member initializers.
-
- Next, all local class members are initialized in the order in
- which they are declared in the class, not the order in which they
- are declared in the initialization list. Actually, it would
- probably be good practice to not use the member initializer to
- initialize class members but instead to initialize them in the
- normal constructor code.
-
- Finally, after the member initializers are all executed in the
- proper order, the main body of the constructor is executed in the
- normal manner.
-
- Page 9-5
-
- Chapter 9 - Multiple Inheritance and Future Directions
-
- USING THE NEW CLASS
- -----------------------------------------------------------------
- The example program named USEDTTM.CPP uses =================
- the datetime class we just built, and like USEDTTM.CPP
- our previous examples, the main program is =================
- kept very simple and straight forward. You
- will note that the default constructor is used for the object
- named now, and the constructor with the member initializers is
- used with the objects named birthday and special. The diligent
- student should have no trouble understanding the remaining code
- in this example.
-
-
- FUTURE DIRECTIONS OF C++
- -----------------------------------------------------------------
- An ANSI committee has been formed to write an ANSI standard for
- C++. They first met in the Spring of 1990 and are expected to
- release the first draft of the standard sometime in 1994. The
- goal for the final release is 1996, but until the new standard is
- released, the C++ language is expected to stay fairly stable.
- However, due to the nature of compiler writers and their desire
- to slightly improve their offerings over their competitors, you
- can bet that the language will not remain static during this
- period.
-
- Many small changes have been added recently that barely affect
- the casual programmer, or even the heavy user of the language.
- You can be sure that the language will evolve slowly and surely
- into a very usable and reliable language. There are two areas,
- however, that should be discussed in a little detail because they
- will add so much to the language in future years. Those two
- topics are parameterized types and exception handling.
-
-
- FUTURE DIRECTIONS - PARAMETERIZED TYPES
- -----------------------------------------------------------------
- Many times, when developing a program, you wish to perform some
- operation on more than one data type. For example you may wish
- to sort a list of integers, another list of floating point
- numbers, and a list of alphabetic strings. It seems silly to
- have to write a separate sort function for each of the three
- types when all three are sorted in the same logical way. With
- parameterized types, you will be able to write a single sort
- routine that is capable of sorting all three of the lists.
-
- This is already available in the Ada language as the generic
- package or procedure. Because it is available in Ada, there is a
- software components industry that provides programmers with
- prewritten and thoroughly debugged software routines that work
- with many different types. When this is generally available in
- C++, there will be a components industry for C++ and precoded,
- debugged and efficient source code will be available off the
- shelf to perform many of the standard operations. These
-
- Page 9-6
-
- Chapter 9 - Multiple Inheritance and Future Directions
-
- operations will include such things as sorts, queues, stacks,
- lists, etc.
-
- Several compiler writers have included templates in their latest
- compilers. The next three example programs will illustrate the
- use of templates with Borland's compiler, but may not work with
- other compilers.
-
-
- THE FIRST TEMPLATE
- -----------------------------------------------------------------
- The example program named TEMPLAT1.CPP is the ==================
- first example of the use of a template. This TEMPLAT1.CPP
- program is so simple it seems silly to even ==================
- bother with it but it will illustrate the use
- of the parameterized type.
-
- The template is given in lines 4 through 8 with the first line
- indicating that it is a template with a single type to be
- replaced, the type ANY_TYPE. This type can be replaced by any
- type which can be used in the comparison operation in line 7. If
- you have defined a class, and you have overloaded the operator
- ">", then this template can be used with objects of your class.
- Thus, you do not have to write a maximum function for each type
- or class in your program.
-
- This function is included automatically for each type it is
- called with in the program, and the code itself should be very
- easy to understand.
-
- The diligent student should realize that nearly the same effect
- can be achieved through use of a macro, except that when a macro
- is used, the strict type checking is not done. Because of this
- and because of the availability of the inline method capability
- in C++, the use of macros is essentially non-existent by
- experienced C++ programmers.
-
-
- A CLASS TEMPLATE
- -----------------------------------------------------------------
- The example program named TEMPLAT2.CPP is a ==================
- little more involved since it provides a TEMPLAT2.CPP
- template for an entire class rather than a ==================
- single function. The template code is given
- in lines 6 through 16 and a little study will show that this is
- an entire class definition. The diligent student will recognize
- that this is a very weak stack class since there is nothing to
- prevent popping data from an empty stack, and there is no
- indication of a full stack. Our intent, however, is to
- illustrate the use of the parameterized type and to do so using
- the simplest class possible.
-
-
-
- Page 9-7
-
- Chapter 9 - Multiple Inheritance and Future Directions
-
- In the main program we create an object named int_stack in line
- 25 which will be a stack designed to store integers, and another
- object named float_stack in line 26 which is designed to store
- float type values. In both cases, we enclose the type we desire
- this object to work with in "<>" brackets, and the system creates
- the object by first replacing all instances of ANY_TYPE with the
- desired type, then creating the object of that type. You will
- note that any type can be used that has an assignment capability
- since lines 12 and 13 use the assignment operator on the
- parameterized type.
-
- Even though the strings are all of differing lengths, we can even
- use the stack to store a stack of strings if we only store a
- pointer to the strings and not the entire string. This is
- illustrated in the object named string_stack declared in line 27
- and used later in the program.
-
- This program should be fairly easy for you to follow if you spend
- a bit of time studying it. You should compile and run it if you
- have a compiler that will handle this new construct.
-
-
- REUSING THE STACK CLASS
- -----------------------------------------------------------------
- The program named TEMPLAT3.CPP uses the same ==================
- class with the template as defined in the TEMPLAT3.CPP
- last program but in this case, it uses the ==================
- date class developed earlier as the stack
- members. More specifically, it uses a pointer to the date class
- as the stack member. Because class assignment is legal, you could
- also store the actual class in the stack rather than just the
- pointer to it. To do so however, would be very inefficient since
- the entire class would be copied into the stack each time it is
- pushed and the entire class would be copied out again when it was
- popped. Use of the pointer is a little more general, so it was
- illustrated here for your benefit.
-
- All three of the previous programs can be compiled and executed
- if you have a compiler that supports templates. Parameterized
- types are a part of the C++ specification, but are not yet
- included in all implementations.
-
-
- FUTURE DIRECTIONS - EXCEPTION HANDLING
- -----------------------------------------------------------------
- A future version of C++ will have some form of exception handling
- to allow the programmer to trap errors and prevent the system
- from completely shutting down when a fatal error occurs. The
- Ada language allows the programmer to trap any error that occurs,
- even system errors, execute some recovery code, and continue on
- with the program execution in a very well defined way. Bjarne
- Stroustrup, working in conjunction with the ANSI-C++ committee,
- has announced that some form of exception handling will be
-
- Page 9-8
-
- Chapter 9 - Multiple Inheritance and Future Directions
-
- implemented but he has not stated exactly what form it would take
- as of this writing.
-
-
- WHAT SHOULD BE YOUR NEXT STEP?
- -----------------------------------------------------------------
- Once again, we have reached a major milestone in C++ programming.
- With the ability to use inheritance, you have nearly all of the
- tools you need to effectively use the object oriented programming
- techniques of C++ and you would do well to stop studying again
- and begin programming. The only topic left with C++ is virtual
- methods which are used for dynamic binding or polymorphism. This
- will be covered in the next two chapters. The vast majority of
- all programming can be done without dynamic binding, and in
- attempting to force it into every program, you could wind up with
- an unreadable mess, so you should approach it slowly.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Page 9-9
-